package com.example.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

@Service
@Slf4j
public class ForkJoinPoolExampleService {

    // 创建 ForkJoinPool 实例，它实现了工作窃取算法
    private final ForkJoinPool forkJoinPool = new ForkJoinPool();

    // 提供公共方法来执行 ForkJoinPool 任务
    public void executeForkJoinTask() {
        // 一个简单的整数数组作为输入
        int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        RecursiveTask<Integer> task = new SumTask(array, 0, array.length);

        // 使用 ForkJoinPool 调用任务
        log.info("ForkJoinPool 任务开始...");
        int result = forkJoinPool.invoke(task);
        log.info("ForkJoinPool 计算结果: {}", result);
    }

    // 内部类 SumTask，继承 RecursiveTask 来实现分治操作
    private static class SumTask extends RecursiveTask<Integer> {
        private static final int THRESHOLD = 2;  // 任务的阈值，任务小于等于该值时不再分解
        private final int[] array;
        private final int start;
        private final int end;

        public SumTask(int[] array, int start, int end) {
            this.array = array;
            this.start = start;
            this.end = end;
        }

        @Override
        protected Integer compute() {
            // 如果任务足够小，则直接计算结果
            if (end - start <= THRESHOLD) {
                int sum = 0;
                log.info("任务 [{} - {}] 足够小，直接计算。", start, end);
                for (int i = start; i < end; i++) {
                    sum += array[i];
                }
                return sum;
            } else {
                // 否则，分解任务
                int mid = (start + end) / 2;
                log.info("任务 [{} - {}] 过大，拆分为 [{} - {}] 和 [{} - {}]", start, end, start, mid, mid, end);

                // 创建子任务
                SumTask leftTask = new SumTask(array, start, mid);
                SumTask rightTask = new SumTask(array, mid, end);

                // 使用 invokeAll 并行执行子任务
                invokeAll(leftTask, rightTask);

                // 合并结果
                int leftResult = leftTask.join();
                int rightResult = rightTask.join();
                log.info("合并子任务结果: [{} - {}] 和 [{} - {}] 的结果为: {} + {} = {}", start, mid, mid, end, leftResult, rightResult, leftResult + rightResult);
                return leftResult + rightResult;
            }
        }
    }
}
